#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

#include "api_handler.h"
#include "api_cmd.h"

void api_handler(uint8_t *data, uint16_t len)
{
    // uint8_t type = data[0];                          // protocol type
    uint8_t cmd = data[1];                           // command
    uint8_t *payload = NULL;                         // payload
    uint16_t payload_len = data[2] | (data[3] << 8); // payload length
    if (payload_len > 0)
        payload = data + 4;

    switch (cmd)
    {
        case CMD_COMMON_GET_BOARD_INFO:
            api_get_board_info(payload, payload_len);
            break;

        case CMD_COMMON_REBOOT:
            api_reboot(payload, payload_len);
            break;

        case CMD_COMMON_FACTORY_RESET:
            api_factory_reset(payload, payload_len);
            break;

        case CMD_COMMON_DFU:
            api_dfu(payload, payload_len);
            break;

        case CMD_COMMON_FIND_ME:
            api_find_me(payload, payload_len);
            break;

        case CMD_COMMON_UART_CONFIG:
            api_uart_config(payload, payload_len);
            break;

        case CMD_COMMON_KEEP_ALIVE:
            api_keep_alive(payload, payload_len);
            break;

        //----------- BLE CENTRAL -----------
        case CMD_BLE_CENTRAL_SCAN:
            api_ble_scan(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_CONNECT:
            api_ble_connect(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_GET_CONNECTED_LIST:
            api_ble_get_connected_list(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_READ:
            api_ble_read(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_WRITE:
            api_ble_write(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_NOTIFY_SET:
            api_ble_notify_set(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_GET_SCAN_PARAMS:
            api_ble_get_scan_params(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_SET_SCAN_PARAMS:
            api_ble_set_scan_params(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_GET_CONN_PARAMS:
            api_ble_get_conn_params(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_SET_CONN_PARAMS:
            api_ble_set_conn_params(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_GET_FILTER_1:
            api_ble_get_filter_1(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_SET_FILTER_1:
            api_ble_set_filter_1(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_GET_FILTER_2:
            api_ble_get_filter_2(payload, payload_len);
            break;

        case CMD_BLE_CENTRAL_SET_FILTER_2:
            api_ble_set_filter_2(payload, payload_len);
            break;

        //----------- BLE PERIPHERAL -----------
        case CMD_BLE_PERIPHERAL_SET_ADV:
            api_ble_set_adv(payload, payload_len);
            break;

        case CMD_BLE_PERIPHERAL_SET_DISCON:
            api_ble_set_discon(payload, payload_len);
            break;

        case CMD_BLE_PERIPHERAL_GET_ADV_PARAMS:
            api_ble_get_adv_params(payload, payload_len);
            break;

        case CMD_BLE_PERIPHERAL_SET_ADV_PARAMS:
            api_ble_set_adv_params(payload, payload_len);
            break;
            
        default:
            printk("Unknown command: %d\n", cmd);
            break;
    }
}

void api_get_board_info(uint8_t *data, uint16_t len)
{

}

void api_reboot(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_factory_reset(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_dfu(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_find_me(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_uart_config(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_keep_alive(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_scan(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_connect(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_get_connected_list(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_write(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_read(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_notify_set(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_get_scan_params(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_set_scan_params(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_get_conn_params(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_set_conn_params(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_get_filter_1(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_set_filter_1(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_get_filter_2(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_set_filter_2(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_set_adv(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_set_discon(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_get_adv_params(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}

void api_ble_set_adv_params(uint8_t *data, uint16_t len)
{
    // TODO: Implement
}
